/**
 * @Author: Sun Rising 
 * @Date: 2020-06-14 08:40:46 
 * @Last Modified by: Sun Rising
 * @Last Modified time: 2020-06-25 18:27:54
 * @Description: 表单元素
 */
 <template>
  <div class="sun-form-item">
    <text class="item-label" v-if="label" :style="'width:'+labelWidth+'rpx'">{{label}}</text>
    <slot></slot>
  </div>
</template>
 
 <script>
export default {
  name: "sunFormItem",
  props: {
    // 输入框标签
    label: {
      type: String,
      default: ""
    },
    // 校验规则
    rule: {
      type: Function,
      default: null
    },
    // 校验触发类型
    trigger: {
      type: String,
      default: "blur"
    },
    // 映射表单字段
    prop: {
      type: String,
      required: true
    }
  },
  inject: ["sunForm"],
  provide() {
    return {
      sunFormItem: this
    };
  },
  data() {
    return {
      // 标签宽度
      labelWidth: this.sunForm.labelWidth
    };
  },
  watch: {
    // 监听方式修改，重新注册事件
    trigger: {
      handler() {
        this.removeValidateEvents();
        this.$nextTick(() => {
          this.addValidateEvents();
        });
      }
    }
  },
  mounted() {
    // 注册元素
    this.sunForm.doRegisteredElement(this);
    // 初始化事件监听
    this.addValidateEvents();
  },
  methods: {
    // 异常管理
    doExceptionMgr(is) {
      this.dispatch("sunInput", "showErrorStyle", is);
    },
    // 查找目标组件并调用目标函数
    dispatch(componentName, eventName, params) {
      var children = this.$children[0];
      var name = children.$options.name;

      while (children && (!name || name !== componentName)) {
        children = children.$children[0];
        if (children) {
          name = children.$options.name;
        }
      }

      if (children) {
        children[eventName](params);
      }
    },
    // 注册事件
    addValidateEvents() {
      if (this.getRule()) {
        if (this.trigger === "blur") this.$on("sun.form.blur", this.doValidate);
        if (this.trigger === "input") this.$on("sun.form.input", this.doValidate);
      }
    },
    // 移出所有事件
    removeValidateEvents() {
      this.$off();
    },
    // 获取校验规则
    getRule() {
      return this.rule || false;
    },
    // 校验方法
    doValidate(value) {
      try {
        const rule = this.getRule();
        if (rule) rule.call(this.$root, value);
        this.doExceptionMgr(false);
      } catch (error) {
        this.sunForm.doShowMessage(error.message);
        this.doExceptionMgr(true);
        return error.message;
      }
    }
  }
};
</script>
 
 <style lang="less" scoped>
.sun-form-item {
  display: flex;
  width: 100%;
  align-items: center;
  & .item-label {
    padding: 0 10rpx;
  }
}
</style>
